Ingeniería Financiera

ITE1731 - Microestructura y Sistemas de Trading


I.F. Sofía Mariana García Mora

I.F. Evelyn Gutiérrez

I.F. Andrea Jiménez Orozco

I.F. Roberto Chávez Guerrero

I.F. José Fernando Flores García

Septiembre 2020 | Repositorio: Link





Laboratorio 3

Análisis del desempeño de Trading

Abstract

Este documento fue elaborado por los I.F. **Sofía Mariana García Mora, Evelyn Gutiérrez, Andrea Jiménez Orozco, Roberto Chávez Guerrero y José Fernando Flores García**, como un trabajo parcial para la materia de **Microestructura y Sistemas de Trading - ITE1731**, la cual es parte del curriculum de la licenciatura en Ingeniería Financiera, ofertada por la universidad **ITESO**. En el presente trabajo se plantea la respuesta a la siguiente pregunta: *¿Cómo análizar el desempeño de la actividad de trading?*


0. Librerías y Dependencias


0.1 Librerías

Para correr este notebook es necesario tener instaladas y/o en el archivo _requirements.txt_ las siguientes librerías :

  • pandas >= 1.1.1
  • numpy >= 1.19.1
  • jupyter >= 1.0.0
  • statistics
  • getpass
  • MetaTrader5 >= 5.0.34
  • datetime </font>

0.2 Dependencias

Para correr este notebook es necesario contar con los siguientes archivos y dependencias externas:

  • files/Accounts.xlsx : Archivo de cuentas de los integrantes del equipo
  • files/Benchmarl_S&P500.xlsx : Archivo con precios de cierre ajustados del índice de referencia utilizado como benchmark </font>


1. Introducción


Se puede llegar a pensar en repetidas ocaciones que el conocimiento financiero o técnico en las inversiones son unas de las variables determinantes para generar un rendimiento considerado como "bueno" dependiendo del contexto. Sin embargo, existe otro enfoque mucho más humano que incluye el análisis de la persona misma que es quien toma una serie de decisiones para llegar a un resultado objetivo. La piscología es una de las ciencias interrelacionadas al momento de hacer trading que influye directamente en las operaciones, y el no considerarlo sería omitir una gran oportunidad para mejorar considerablemente el desempeño.

¿Por qué es esto? La mayoría de nosotros puede cohincidir en que tomamos decisiones concientes o inconsientes. Pero quizá estas decisiones cualquiera sea su modalidad pueden estar sesgadas, es decir existe un peso desproporcionado a favor o en contra de una cosa, persona o grupo en comparación con otra, generalmente de una manera que se considera injusta.

Cada ser humano es diferente y por ende su proceso para tomar decisiones, pero existe la posibilidad de analiar y encontrar patrones que determinen dichos sesgos en donde el primer paso para corregirlos es ser conciente de ellos.

El Comportamiento en las Finanzas o mejor conocido por su nombre en inglés como Behavioral Finance, es una nueva rama de estudio que fusiona como ya se mencionó anteriormente aspectos psicológicos de las personas en el ámbito financiero. El objetivo principal es hacernos concientes de dichos sesgos o elementos psicologicos para tratar de ser objetivos y corregirlos.

El presente proyecto tiene como finalidad abordar desde una de las muchas perspectivas, el acto de realizar trading, que como bien sabemos es la operación misma de comprar/vender un activo cuyo prósito sigue una estrategia y esta se compone de varias decisiones. Por lo que se pretende primeramente hacer un análisis general de la cuenta para posteriormente identificar si existieron sesgos o no al momento de ejecutar operaciones.

brain-and-sketching.jpg

</font>


2. Objetivos


El objetivo principal de este laboratorio es analizar a profunidad el proceso de inversión de un trader e identificar posibles sesgos, ya que al desarrollar métricas y procesos para analizar la información que se genera a partir de la cuenta de trading, se puede encontrar una manera de generalizar ciertos aspectos de una estrategia y por ende áreas de mejora.

El enfoque en el cual se centrará una parte importante del proceso tiene que ver con el estudio de un sesgo conocido como disposition effect, el cuál de manera breve nos habla de las veces en las que se tiene una aversión a la pérdida, postergando la toma de péridas y a su vez la toma rápida de ganancias. Ya que la intensidad del dolor a la pérdida es mucho mayor a la intensidad del placer a las ganancias.

No es ningun secreto que para invertir en los mercados además de contar con fuertes conocimientos se necesita también inteligencia emocional y es inclusive en algunos casos la línea que define el éxito de un trader, este análisis busca encontrar una manera sistemática de evaluar dichos sesgos de cualquier cuenta y hacer al trader mas conciente de sus decisiones a lo largo del proceso.

Para poner en marcha uno de los elementos escenciales para comenzar como lo es el historial de operaciones cada integrante del equipo tuvo un proceso previo de 12 días en donde por medio de una cuenta demo en MetaTrader5 se realizarón operaciones de trading en el mercado de divisas (FX) por lo menos una al día.

La estructura del proyecto se compone de la siguiente manera:

1. Análisis general de la cuenta para responder a aspectos básicos como:

- ¿Cuál fue el capital acumulado de la cuenta al final del periodo?
- ¿Cuáles fueron los activos en los que se invirtió más capital?
- ¿Cuántas operaciones se cerraron con pérdida y con ganancia?
- ¿Cuál fue el momento en donde se presentó la máxima péridida flotante y la mayor ganancia flotante?
- ¿Cómo se comportó el rendimiento acumulado y al final de la cuenta versus un benchmark en el mercado?

2. Realizar de manera sistemática una evaluación del sesgo "disposition effect":

- Definir operaciones ancla (ganadoras) y operaciones abiertas al tiempo de cierre. 
- Calcular la péridad flotante de dichas operaciones abiertas por cada ancla y contabilizar por cada ocurrencia:
    + Status quo
    + Aversión a la pérdida
    + Sensibilidad decreciente

De esta manera el trader podrá visualizar de manera sintetizada el resultado general de sus operaciones y si en efecto incurrió en un sesgo.


3. Datos


Para leer cada una de las cuenta de las operaciones historicas fue necesario conectar con la API de MetaTrader5. Ya sea ingresando el usuario y contraseña en el archivo Accounts.csv con el nombre correspondiente o bien responiendo "Otros" que descargará de la misma manera automática dicha información.

En caso de no ingresar un nombre válido o cuenta incorrecta, se deplegará una leyenda informando el tipo de error. Esto es bastante útil pues se busca que cualquier persona con una cuenta en MetaTrader5 realice el análisis.

mensaje%20cuenta.PNG

In [15]:
#Librerías
from functions import *
from visualizations import *
import warnings
warnings.filterwarnings("ignore")

La información desplegada corresponde a cada una de las operaciones realizadas durante el periodo de tiempo la cual incluye elementos indispensables como dirección, volumen, instrumento, tiempo de apertura y cierra así como su precio correspondiente y finalmente pérdidas y ganancias.

In [2]:
#Se muestra el ejemplo crudo de una cuenta
f_leer_archivo()
Los nombres son: ['Sofia', 'Chavez', 'Andrea', 'Fernando', 'Evelyn ', 'Otro']
Ingrese nombre del integrante a analizar: Fernando
Se inició con éxito la cuenta
Out[2]:
Position Time Symbol Type Volume Price Time.1 Price.1 Commission Swap Profit
0 872818543 1613687752 EURUSD buy 0.02 1.20908 1613687758 1.20909 0.0 0.00 0.02
1 873084407 1613711769 EURUSD buy 0.10 1.20856 1613720194 1.20954 0.0 0.00 9.80
2 874838330 1613968663 GBPUSD buy 2.80 1.40189 1614135981 1.41588 0.0 -1.12 3917.20
3 879607110 1614184117 EURUSD buy 7.00 1.21329 1614186629 1.21200 0.0 0.00 -903.00
4 879593812 1614183711 USDJPY buy 3.70 105.98600 1614267174 106.19300 0.0 -1.05 721.23
5 882059789 1614280176 EURUSD buy 7.00 1.22333 1614280857 1.22334 0.0 0.00 7.00
6 882193239 1614283752 AUDCAD sell 1.00 0.99267 1614288975 0.99357 0.0 0.00 -71.62
7 877975804 1614104941 AUDUSD buy 0.60 0.79136 1614295445 0.78701 0.0 15.12 -261.00
8 884211062 1614363107 CADJPY buy 1.00 84.06700 1614368744 83.79800 0.0 0.00 -252.24
9 874666625 1613955559 GBPUSD buy 0.50 1.40185 1614612227 1.39121 0.0 -0.70 -532.00
10 885568950 1614613335 EURJPY sell 2.00 128.56800 1614613416 128.56700 0.0 0.00 1.87
11 885564796 1614613184 EURJPY buy 7.00 128.55100 1614613634 128.55700 0.0 0.00 39.36
12 885576932 1614613683 EURJPY buy 7.00 128.57000 1614616824 128.41300 0.0 0.00 -1030.91
13 884841352 1614576421 EURUSD sell 1.50 1.20851 1614896607 1.19630 0.0 -7.50 1831.50
14 889219216 1614827478 USDCHF sell 7.00 0.91989 1614910226 0.92940 0.0 -7.54 -7162.69
15 887186855 1614704057 GBPUSD buy 7.00 1.39280 1614944167 1.38130 0.0 -7.00 -8050.00
16 885540715 1614612308 AUDUSD sell 1.50 0.77351 1616057282 0.78397 0.0 -421.80 -1569.00

4. Procesos


Parte 1. Estadística Descriptiva

El archivo de functions.py contiene los siguientes DataFrames a continuación necesarios para la construcción de la primera parte:

  • f_leer_archivo: Lectura y visualización del historial de operaciones.

  • f_pip_size: Cáluclo del tamaño de pips por instrumento, pues al ser pares de divisas la conversión es diferente para cada una. Este paso es relevante para el cálculo del P&L

  • f_columnas_tiempos: Cambia las columnas de apertura y cierre de operaciones a formato datetime con la intención de hacer más sencilla la lectura y manejo de datos. A su vez determina el tiempo transcurrido en el que se mantuvo abierta la operación.

  • f_columnas_pips: Se expresan los pips generados por operaciones, es decir pérdidas y ganancias expresadas en esta unidad, de igual manera el P&L acumulado.

Finalmente se agregan dos últimos apartados, el primero correspondiente al ranking de instrumentos más utilizados y segundo las estadisticas básicas del historial de trading.

In [23]:
data, data2, data3, data4, df1_est_ba, df2_ranking = Full_Part1()
Los nombres son: ['Sofia', 'Chavez', 'Andrea', 'Fernando', 'Evelyn ', 'Otro']
Ingrese nombre del integrante a analizar: Fernando
Se inició con éxito la cuenta
Primer análisis realizado con éxito
In [5]:
#Ejemplo de tamaño de pips independientemente del intrumento
f_pip_size('USDJPY'), f_pip_size('AUDUSD')
Out[5]:
(100, 10000)
In [6]:
f_columnas_tiempos = data2.loc[:, ['close_time',"open_time",'Type',"Symbol","Profit","time"]]
f_columnas_tiempos.head()
Out[6]:
close_time open_time Type Symbol Profit time
0 2021-02-18 16:35:58 2021-02-18 16:35:52 buy EURUSD 0.02 6.0
1 2021-02-19 01:36:34 2021-02-18 23:16:09 buy EURUSD 9.80 8425.0
2 2021-02-23 21:06:21 2021-02-21 22:37:43 buy GBPUSD 3917.20 167318.0
3 2021-02-24 11:10:29 2021-02-24 10:28:37 buy EURUSD -903.00 2512.0
4 2021-02-25 09:32:54 2021-02-24 10:21:51 buy USDJPY 721.23 83463.0
In [7]:
f_columnas_pips = data2.loc[:, ['close_time',"open_time",'Type',"Symbol","pips","pips_acm","profit_acm"]]
f_columnas_pips.head()
Out[7]:
close_time open_time Type Symbol pips pips_acm profit_acm
0 2021-02-18 16:35:58 2021-02-18 16:35:52 buy EURUSD 0.1 0.1 0.02
1 2021-02-19 01:36:34 2021-02-18 23:16:09 buy EURUSD 9.8 9.9 9.82
2 2021-02-23 21:06:21 2021-02-21 22:37:43 buy GBPUSD 139.9 149.8 3927.02
3 2021-02-24 11:10:29 2021-02-24 10:28:37 buy EURUSD -12.9 136.9 3024.02
4 2021-02-25 09:32:54 2021-02-24 10:21:51 buy USDJPY 20.7 157.6 3745.25
In [8]:
#Resultados de estadísticas básicas
df1_est_ba
Out[8]:
medida valor descripcion
0 Ops totales 17.00 Operaciones totales
1 Ganadoras 8.00 Operaciones ganadoras
2 Ganadoras_c 6.00 Operaciones ganadoras de compra
3 Ganadoras_v 2.00 Operaciones ganadoras de venta
4 Perdedoras 9.00 Operaciones perdedoras
5 Perdedoras_c 6.00 Operaciones perdedoras de compra
6 Perdedoras_v 3.00 Operaciones perdedoras de venta
7 Mediana(Profit) -71.62 Mediana de profit de operaciones
8 Mediana(Pips) -9.00 Mediana de pips de operaciones
9 r_efectividad 0.47 Ganadoras Totales/Operaciones Totales
10 r_proporcion 0.89 Ganadoras Totales/Perdedoras Totales
11 r_efectividad_c 0.35 Ganadoras Compras/Operaciones Totales
12 r_efectividad_v 0.12 Ganadoras Ventas/Operaciones Totales
In [9]:
# Resultados del ranking
df2_ranking
Out[9]:
symbol rank (%)
0 USDJPY 100.0
1 EURUSD 80.0
2 EURJPY 67.0
3 GBPUSD 33.0
4 AUDCAD 0.0
5 AUDUSD 0.0
6 CADJPY 0.0
7 USDCHF 0.0

Parte 2. Métricas de Atribución al Desempeño

In [10]:
pie_chart(df2_ranking)

Las métricas de atribución al desempeño ayudan al trader a analizar las ganancias por día y acumuladas respecto al inicio. Calculando el capital acumulado y por ende su evolución. Con esta información es posible obtener otros puntos relevantes como el DrawDown, DrawUp y Sharpe Ratio en su forma original, es decir comparando contra la tasa de interés libre de riesgo y en su forma actualizada descrita por el CFA cuya comparación se basa contra el benchmark del mercado, en este caso el S&P 500.

In [12]:
df_capital = f_evolucion_capital(data3)
df_capital.head()
Out[12]:
Profit profit_acm_d cap_acum
close_time_
2021-02-19 9.8 9.8 1000009.8
2021-02-20 0.0 9.8 1000009.8
2021-02-21 0.0 9.8 1000009.8
2021-02-22 0.0 9.8 1000009.8
2021-02-23 3917.2 3927.0 1003927.0
In [18]:
est_mad = f_estadisticas_mad(0.001, df_capital)
est_mad
Out[18]:
metrica Valor Descripción
0 sharpe_original Cantidad -0.290996 Sharpe Ratio Fórmula Original
1 sharpe_actualizado Cantidad 0.0242097 Sharpe Ratio Fórmula Actualizado
2 drawdown_capi Fecha Final 15662.5 Máxima pérdida flotante registrada
3 drawup_capi Fecha Final -15662.5 Máxima ganancia flotante registrada
4 drawdown_capi Fecha Inicial 2021-03-05 Fecha inicial del DrawDown de Capital
5 drawdown_capi Fecha Final 2021-03-05 Fecha final del DrawDown de Capital
6 drawup_capi Fecha Inicial 2021-03-05 Fecha inicial del DrawUp de Capital
7 drawup_capi Fecha Final 2021-03-05 Fecha final del DrawUp de Capital

Parte 3. Behavioral Finance

Como se mencionó anteriormente en esta parte se pretende contabilizar las veces que ocurrió el sesgo denominado "disposition effect" el cuál habla sobre la dificultad de asumir péridas. El cual se ve reflejando en operaciones con péridida flotante por más tiempo y operaciones con toma de ganancia apresuradas con el fin de compensar.

En la primera función denominada f_be_de_parte1 se extraen de manera separada las operaciones ganadoras, consideradas como ancla aquellas cerradas con un monto positivo. Y operaciones de pérdidas en donde por medio de una interación se determino cuales se encontraban abiertas al momento de que otra operación ancla. Finalmente para la determinación de la pérdida flotante, se descargaron precios intradiarios desde la API de MetaTrader5.

Por lo tanto la segunda parte llamda f_be_de_parte2 es un diccionario que contabiliza las ocurrencias y guarda dentro información relevante tanto de la operación ancla (ganadora), así como a la correspondiente abierta con pérdida flotante. Cabe mencionar que existen operaciones cerradas a las cuales no les correspondía ninguna abierta con pérdida, por lo que no es de extrañarse que no se encuentren todas las fechas completas.

In [24]:
ocurrencias, df_anclas =   f_be_de_parte1(data3)
In [25]:
df_anclas.head()
Out[25]:
close_time open_time Type Symbol Profit profit_acm capital_acm Ratio Time Time.1 Price Volume
0 2021-02-18 16:35:58 2021-02-18 16:35:52 buy EURUSD 0.02 0.02 100000.02 1.000000 1613687752 1613687758 1.20908 0.02
1 2021-02-19 01:36:34 2021-02-18 23:16:09 buy EURUSD 9.80 9.82 100009.82 0.997963 1613711769 1613720194 1.20856 0.10
2 2021-02-23 21:06:21 2021-02-21 22:37:43 buy GBPUSD 3917.20 3927.02 103927.02 0.997499 1613968663 1614135981 1.40189 2.80
3 2021-02-25 09:32:54 2021-02-24 10:21:51 buy USDJPY 721.23 3745.25 103745.25 0.192572 1614183711 1614267174 105.98600 3.70
4 2021-02-25 13:20:57 2021-02-25 13:09:36 buy EURUSD 7.00 3752.25 103752.25 0.001866 1614280176 1614280857 1.22333 7.00
In [26]:
ocurrencias.head()
Out[26]:
Type Symbol Volume Profit Price pips close_time_ancla float_price float_pips float_P&L
0 buy AUDUSD 0.6 -261.0 0.79136 -43.5 2021-02-23 21:06:21 0.791020 -3.400000 -20.4
1 sell EURUSD 1.5 1831.5 1.20851 122.1 2021-03-01 09:43:36 1.208653 -1.433333 -21.5
2 sell AUDUSD 1.5 -1569.0 0.77351 -104.6 2021-03-01 09:43:36 0.776300 -27.900000 -418.5
3 sell EURUSD 1.5 1831.5 1.20851 122.1 2021-03-01 09:47:14 1.208760 -2.500000 -37.5
4 sell AUDUSD 1.5 -1569.0 0.77351 -104.6 2021-03-01 09:47:14 0.776270 -27.600000 -414.0
In [30]:
diccionario = f_be_de_parte2(ocurrencias,df_anclas)
diccionario['ocurrencias']
Out[30]:
{'Cantidad': 7,
 'ocurrencia_1': {'timestamp': Timestamp('2021-02-23 21:06:21'),
  'operaciones': {'ganadoras': {'instrumento': 'GBPUSD',
    'volumen': 2.8,
    'sentido': 'buy',
    'profit_ganadora': 3917.2},
   'perdedoras': {'instrumento': 'AUDUSD',
    'volumen': 0.6,
    'sentido': 'buy',
    'profit_perdedora': -20.4}},
  'ratio_cp_profit_acm': 0.01,
  'ratio_cg_profit_acm': 1.0,
  'ratio_cp_cg': 0.01},
 'ocurrencia_2': {'timestamp': Timestamp('2021-03-01 09:43:36'),
  'operaciones': {'ganadoras': {'instrumento': 'EURJPY',
    'volumen': 2.0,
    'sentido': 'sell',
    'profit_ganadora': 1.87},
   'perdedoras': {'instrumento': 'EURUSD',
    'volumen': 1.5,
    'sentido': 'sell',
    'profit_perdedora': -21.5}},
  'ratio_cp_profit_acm': 0.01,
  'ratio_cg_profit_acm': 0.0,
  'ratio_cp_cg': 11.5},
 'ocurrencia_3': {'timestamp': Timestamp('2021-03-01 09:43:36'),
  'operaciones': {'ganadoras': {'instrumento': 'EURJPY',
    'volumen': 2.0,
    'sentido': 'sell',
    'profit_ganadora': 1.87},
   'perdedoras': {'instrumento': 'AUDUSD',
    'volumen': 1.5,
    'sentido': 'sell',
    'profit_perdedora': -418.5}},
  'ratio_cp_profit_acm': 0.16,
  'ratio_cg_profit_acm': 0.0,
  'ratio_cp_cg': 223.8},
 'ocurrencia_4': {'timestamp': Timestamp('2021-03-01 09:47:14'),
  'operaciones': {'ganadoras': {'instrumento': 'EURJPY',
    'volumen': 7.0,
    'sentido': 'buy',
    'profit_ganadora': 39.36},
   'perdedoras': {'instrumento': 'EURUSD',
    'volumen': 1.5,
    'sentido': 'sell',
    'profit_perdedora': -37.5}},
  'ratio_cp_profit_acm': 0.01,
  'ratio_cg_profit_acm': 0.01,
  'ratio_cp_cg': 0.95},
 'ocurrencia_5': {'timestamp': Timestamp('2021-03-01 09:47:14'),
  'operaciones': {'ganadoras': {'instrumento': 'EURJPY',
    'volumen': 7.0,
    'sentido': 'buy',
    'profit_ganadora': 39.36},
   'perdedoras': {'instrumento': 'AUDUSD',
    'volumen': 1.5,
    'sentido': 'sell',
    'profit_perdedora': -414.0}},
  'ratio_cp_profit_acm': 0.15,
  'ratio_cg_profit_acm': 0.01,
  'ratio_cp_cg': 10.52},
 'ocurrencia_6': {'timestamp': Timestamp('2021-03-04 16:23:27'),
  'operaciones': {'ganadoras': {'instrumento': 'EURUSD',
    'volumen': 1.5,
    'sentido': 'sell',
    'profit_ganadora': 1831.5},
   'perdedoras': {'instrumento': 'USDCHF',
    'volumen': 7.0,
    'sentido': 'sell',
    'profit_perdedora': -3020.23}},
  'ratio_cp_profit_acm': 0.87,
  'ratio_cg_profit_acm': 0.53,
  'ratio_cp_cg': 1.65},
 'ocurrencia_7': {'timestamp': Timestamp('2021-03-04 16:23:27'),
  'operaciones': {'ganadoras': {'instrumento': 'EURUSD',
    'volumen': 1.5,
    'sentido': 'sell',
    'profit_ganadora': 1831.5},
   'perdedoras': {'instrumento': 'AUDUSD',
    'volumen': 1.5,
    'sentido': 'sell',
    'profit_perdedora': -796.5}},
  'ratio_cp_profit_acm': 0.23,
  'ratio_cg_profit_acm': 0.53,
  'ratio_cp_cg': 0.43}}
In [31]:
# Segunda parte del diccionario, mostrando Disposition effect
diccionario["resultados"] ['dataframe']
Out[31]:
ocurrencias status_quo aversion_perdida sensibilidad_decreciente
0 7 42.86% 42.86% No

5. Conclusiones

A partir de los análisis generados se pueden llegar a diversas conclusiones.


Primeramente, los trades generados de forma manual, no fueron constantes, es decir, los volumenes, así como los riesgos que se tomaron no resultaron iguales en todos los trades, esto debido a que no fueron generados por traders con una larga experiencia en el mundo del trading.


Por otra parte, esa falta de experiencia en el mundo del trading podría causar mayores incidencias en los sesgos analizados en la rama de behavioral finance.


Finalmente, se comprendió la importancia que tiene el behavioral finance en el trading, la variedad de sesgso que pueden ocurrir, y cómo afectan al desempeño del trading, pueden ser la base de los sistemas de trading algorítmico, donde algoritmos automatizados crean esas órdenes de compra y venta, ya que para hacerlo correctamente sus parámetros deben estar correctamente delimitados.